#include <easy3d/algo_ext/surfacer.h>
#include <easy3d/core/plane.h>
#include <easy3d/core/surface_mesh.h>
#include <easy3d/core/vec.h>

#include <memory>
#include <utility>
#include <vector>

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>


#ifndef BINDER_PYBIND11_TYPE_CASTER
	#define BINDER_PYBIND11_TYPE_CASTER
	PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>, false)
	PYBIND11_DECLARE_HOLDER_TYPE(T, T*, false)
	PYBIND11_MAKE_OPAQUE(std::shared_ptr<void>)
#endif

void bind_easy3d_algo_ext_surfacer(pybind11::module_& m)
{
	{ // easy3d::Surfacer file:easy3d/algo_ext/surfacer.h line:52
		pybind11::class_<easy3d::Surfacer, std::shared_ptr<easy3d::Surfacer>> cl(m, "Surfacer", "A collection of mesh (and polygon soup) processing functions.\n\n \n\n \n This class collects some related algorithms implemented using CGAL.\n          It allows (re)orientation, detecting and resolving topological issues (e.g., duplicate vertices/faces,\n          self intersection), and clipping/splitting/slicing of a surface mesh.\n\n \n OverlappingFaces and SelfIntersection.");
		cl.def( pybind11::init( [](){ return new easy3d::Surfacer(); } ) );
		cl.def_static("stitch_borders", (int (*)(class easy3d::SurfaceMesh *)) &easy3d::Surfacer::stitch_borders, "Stitches together border halfedges in a polygon mesh.\n\n \n The pairs of halfedges to be stitched are automatically found amongst all border halfedges.\n Two border halfedges h1 and h2 can be stitched if the points associated to the source and target vertices\n of h1 are the same as those of the target and source vertices of h2 respectively.\n\n \n The number of pairs of halfedges that were stitched.\n\n \n merge_reversible_connected_components\n\nC++: easy3d::Surfacer::stitch_borders(class easy3d::SurfaceMesh *) --> int", pybind11::arg("mesh"));
		cl.def_static("merge_reversible_connected_components", (void (*)(class easy3d::SurfaceMesh *)) &easy3d::Surfacer::merge_reversible_connected_components, "Reverses the connected components having incompatible boundary cycles that could be merged if their\n orientation were made compatible, and stitches them. Connected components are examined by increasing number\n of faces.\n\n \n Stitching occurs only if incompatible boundary cycles exists and the corresponding connected\n            components are reversible.\n\n \n stitch_borders()\n\nC++: easy3d::Surfacer::merge_reversible_connected_components(class easy3d::SurfaceMesh *) --> void", pybind11::arg("mesh"));
		cl.def_static("orient_and_stitch_polygon_soup", (bool (*)(class easy3d::SurfaceMesh *)) &easy3d::Surfacer::orient_and_stitch_polygon_soup, "Tries to consistently orient and stitch a mesh (treated as a polygon soup).\n \n\n Internally, it calls\n      orient_and_stitch_polygon_soup(std::vector<vec3>& points, std::vector<Polygon>& polygons).\n \n\n merge_reversible_connected_components()\n\nC++: easy3d::Surfacer::orient_and_stitch_polygon_soup(class easy3d::SurfaceMesh *) --> bool", pybind11::arg("mesh"));
		cl.def_static("orient_closed_triangle_mesh", (void (*)(class easy3d::SurfaceMesh *)) &easy3d::Surfacer::orient_closed_triangle_mesh, "Makes each connected component of a closed triangle surface mesh inward or outward oriented.\n \n\n mesh.is_triangle_mesh(), mesh.is_closed()\n \n\n The input mesh.\n\nC++: easy3d::Surfacer::orient_closed_triangle_mesh(class easy3d::SurfaceMesh *) --> void", pybind11::arg("mesh"));
		cl.def_static("orient_and_stitch_polygon_soup", (bool (*)(class std::vector<class easy3d::Vec<3, float> > &, class std::vector<class std::vector<int> > &)) &easy3d::Surfacer::orient_and_stitch_polygon_soup, "Tries to consistently orient and stitch a polygon soup.\n \n\n When it is not possible to produce a combinatorial manifold surface, some points are duplicated.\n\n The algorithm is described in\n   - A.Guéziec, et al. Cutting and stitching: Converting sets of polygons to manifold surfaces. TVCG 2001.\n\n \n Points of the soup of polygons. Some additional points might be pushed back to resolve\n        non-manifoldness or non-orientability issues.\n \n\n Each element describes a polygon represented by the index of its vertices in \n        If needed the order of the indices of a polygon might be reversed.\n \n\n  if the orientation operation succeeded.  if some points were duplicated, thus\n         producing a self-intersecting polyhedron.\n\nC++: easy3d::Surfacer::orient_and_stitch_polygon_soup(class std::vector<class easy3d::Vec<3, float> > &, class std::vector<class std::vector<int> > &) --> bool", pybind11::arg("points"), pybind11::arg("polygons"));
		cl.def_static("repair_polygon_soup", (void (*)(class std::vector<class easy3d::Vec<3, float> > &, class std::vector<class std::vector<int> > &)) &easy3d::Surfacer::repair_polygon_soup, "Repairs a given polygon soup through various repairing operations.\n \n\n This function carries out the following tasks, in the same order as they are listed:\n  - merging of duplicate points, using CGAL::Polygon_mesh_processing::merge_duplicate_points_in_polygon_soup();\n  - simplification of polygons to remove geometrically identical consecutive vertices;\n  - splitting of \"pinched\" polygons, that is polygons in which a geometric position appears more than once.\n    The splitting process results in multiple non-pinched polygons;\n  - removal of invalid polygons, that is polygons with fewer than 2 vertices;\n  - removal of duplicate polygons, using Polygon_mesh_processing::merge_duplicate_polygons_in_polygon_soup();\n  - removal of isolated points, using Polygon_mesh_processing::remove_isolated_points_in_polygon_soup().\n \n\n The point and polygon containers will be modified by the repairing operations, and thus the indexation\n of the polygons will also be changed.\n\nC++: easy3d::Surfacer::repair_polygon_soup(class std::vector<class easy3d::Vec<3, float> > &, class std::vector<class std::vector<int> > &) --> void", pybind11::arg("points"), pybind11::arg("polygons"));
		cl.def_static("repair_polygon_soup", (void (*)(class easy3d::SurfaceMesh *)) &easy3d::Surfacer::repair_polygon_soup, "Repairs a given polygon mesh through various repairing operations.\n \n\n This function carries out the following tasks, in the same order as they are listed:\n  - merging of duplicate points;\n  - simplification of faces to remove geometrically identical consecutive vertices;\n  - splitting of \"pinched\" faces, that is face in which a geometric position appears more than once.\n    The splitting process results in multiple non-pinched faces;\n  - removal of invalid faces, that is faces with fewer than 2 vertices;\n  - removal of duplicate faces;\n  - removal of isolated points.\n This function treats the input mesh as a polygon soup. Internally, it calls\n clean_polygon_soup(std::vector<vec3>& points, std::vector<Polygon>& polygons).\n \n\n The point and face containers will be modified by the repairing operations, and thus the indexation\n of the polygons will also be changed.\n\nC++: easy3d::Surfacer::repair_polygon_soup(class easy3d::SurfaceMesh *) --> void", pybind11::arg("mesh"));
		cl.def_static("remove_degenerate_faces", [](class easy3d::SurfaceMesh * a0) -> unsigned int { return easy3d::Surfacer::remove_degenerate_faces(a0); }, "", pybind11::arg("mesh"));
		cl.def_static("remove_degenerate_faces", (unsigned int (*)(class easy3d::SurfaceMesh *, float)) &easy3d::Surfacer::remove_degenerate_faces, "Remove degenerate faces.\n \n\n Any triangle with an edge length smaller than a given threshold is consider degenerate and will\n         be removed by the edge collapse operation.\n \n\n The edge length threshold.\n \n\n The number of faces removed.\n\nC++: easy3d::Surfacer::remove_degenerate_faces(class easy3d::SurfaceMesh *, float) --> unsigned int", pybind11::arg("mesh"), pybind11::arg("length_threshold"));
		cl.def_static("detect_overlapping_faces", [](class easy3d::SurfaceMesh * a0, class std::vector<struct std::pair<struct easy3d::SurfaceMesh::Face, struct easy3d::SurfaceMesh::Face> > & a1, class std::vector<struct std::pair<struct easy3d::SurfaceMesh::Face, struct easy3d::SurfaceMesh::Face> > & a2) -> void { return easy3d::Surfacer::detect_overlapping_faces(a0, a1, a2); }, "", pybind11::arg("mesh"), pybind11::arg("duplicate_faces"), pybind11::arg("folding_faces"));
		cl.def_static("detect_overlapping_faces", (void (*)(class easy3d::SurfaceMesh *, class std::vector<struct std::pair<struct easy3d::SurfaceMesh::Face, struct easy3d::SurfaceMesh::Face> > &, class std::vector<struct std::pair<struct easy3d::SurfaceMesh::Face, struct easy3d::SurfaceMesh::Face> > &, double)) &easy3d::Surfacer::detect_overlapping_faces, "Detects duplicate faces and folding faces.\n \n\n Two triangle faces are said duplicate if they have the same geometry (vertices within a distance\n         threshold). Two triangle faces are said folding if they are coplanar, share one edge (i.e., have\n         the same edge geometry), and partially overlap.\n \n\n Returns the duplicate face pairs found.\n \n\n Returns the folding face pairs found.\n \n\n Two vertices are considered coincident if there distance is smaller than it.\n \n\n mesh.is_triangle_mesh().\n\nC++: easy3d::Surfacer::detect_overlapping_faces(class easy3d::SurfaceMesh *, class std::vector<struct std::pair<struct easy3d::SurfaceMesh::Face, struct easy3d::SurfaceMesh::Face> > &, class std::vector<struct std::pair<struct easy3d::SurfaceMesh::Face, struct easy3d::SurfaceMesh::Face> > &, double) --> void", pybind11::arg("mesh"), pybind11::arg("duplicate_faces"), pybind11::arg("folding_faces"), pybind11::arg("dist_threshold"));
		cl.def_static("remove_overlapping_faces", [](class easy3d::SurfaceMesh * a0) -> unsigned int { return easy3d::Surfacer::remove_overlapping_faces(a0); }, "", pybind11::arg("mesh"));
		cl.def_static("remove_overlapping_faces", [](class easy3d::SurfaceMesh * a0, bool const & a1) -> unsigned int { return easy3d::Surfacer::remove_overlapping_faces(a0, a1); }, "", pybind11::arg("mesh"), pybind11::arg("folding_faces"));
		cl.def_static("remove_overlapping_faces", (unsigned int (*)(class easy3d::SurfaceMesh *, bool, double)) &easy3d::Surfacer::remove_overlapping_faces, "Removes duplicate faces and and folding faces.\n \n\n Two triangle faces are said duplicate if they have the same geometry (vertices within a distance\n         threshold). Two triangle faces are said folding if they are coplanar, share one edge (i.e., have\n         the same edge geometry), and partially overlap.\n \n\n  also to remove folding faces.\n \n\n The number of faces that have been deleted.\n \n\n mesh.is_triangle_mesh().\n\nC++: easy3d::Surfacer::remove_overlapping_faces(class easy3d::SurfaceMesh *, bool, double) --> unsigned int", pybind11::arg("mesh"), pybind11::arg("folding_faces"), pybind11::arg("dist_threshold"));
		cl.def_static("detect_self_intersections", (class std::vector<struct std::pair<struct easy3d::SurfaceMesh::Face, struct easy3d::SurfaceMesh::Face> > (*)(class easy3d::SurfaceMesh *)) &easy3d::Surfacer::detect_self_intersections, "Collects all pairs of intersecting faces of a triangulated surface mesh.\n \n\n Two faces are said to intersect if the corresponding triangles intersect and the intersection is\n not an edge nor a vertex incident to both faces.\n \n\n mesh.is_triangle_mesh().\n \n\n The triangle surface mesh to be checked.\n \n\n All pairs of non-adjacent faces that intersect.\n\nC++: easy3d::Surfacer::detect_self_intersections(class easy3d::SurfaceMesh *) --> class std::vector<struct std::pair<struct easy3d::SurfaceMesh::Face, struct easy3d::SurfaceMesh::Face> >", pybind11::arg("mesh"));
		cl.def_static("remesh_self_intersections", [](class easy3d::SurfaceMesh * a0) -> bool { return easy3d::Surfacer::remesh_self_intersections(a0); }, "", pybind11::arg("mesh"));
		cl.def_static("remesh_self_intersections", (bool (*)(class easy3d::SurfaceMesh *, bool)) &easy3d::Surfacer::remesh_self_intersections, "Detects and remesh the intersecting faces.\n \n\n mesh.is_triangle_mesh().\n \n\n The input mesh. If self intersection exists, it carries the remeshed model. Otherwise it remains\n             unchanged.\n \n\n Stitch the borders\n \n\n  if remesh actually occurred (i.e., self intersection was detected).\n\nC++: easy3d::Surfacer::remesh_self_intersections(class easy3d::SurfaceMesh *, bool) --> bool", pybind11::arg("mesh"), pybind11::arg("stitch"));
		cl.def_static("slice", (class std::vector<class std::vector<class std::vector<class easy3d::Vec<3, float> > > > (*)(class easy3d::SurfaceMesh *, const class std::vector<class easy3d::GenericPlane<float> > &)) &easy3d::Surfacer::slice, "Computes the intersection of a set of planes with a triangle surface mesh.\n \n\n mesh.is_triangle_mesh(), !does_self_intersect(SurfaceMesh* mesh).\n \n\n The input triangle mesh.\n \n\n The set of planes to intersect the triangle surface mesh with.\n \n\n The intersecting polylines by all the planes. The  entry denotes the polylines created by\n         the  plane. Each resulting polyline  is oriented such that for two consecutive\n         points  and  in  the normal vector of the face(s) containing the segment pq,\n         the vector  and the normal of  is a direct orthogonal basis. The normal vector of\n         each face is chosen to point on the side of the face where its sequence of vertices is seen\n         counterclockwise.\n \n\n An edge shared by two faces included in plane will not be reported. For example, if plane passes\n       though one face of a cube, only one closed polyline will be reported (the boundary of the face).\n \n\n slice(SurfaceMesh *mesh, const Plane3 &plane).\n\nC++: easy3d::Surfacer::slice(class easy3d::SurfaceMesh *, const class std::vector<class easy3d::GenericPlane<float> > &) --> class std::vector<class std::vector<class std::vector<class easy3d::Vec<3, float> > > >", pybind11::arg("mesh"), pybind11::arg("planes"));
	}
}
